﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Bugtracker;

using WikiBugtracker.Settings;
using WikiBugtracker.WikiCommon;

namespace WikiBugtracker
{
    public class MyBugtracker : Bugtracker.Bugtracker
    {
        private RootManager root_manager_ = null;

        private RootManager RootManager
        {
            get { return root_manager_; }
        }

        private Root Root
        {
            get { return root_manager_.LoadRoot(); }
        }

        private Project Project(String project_name)
        {
            return root_manager_.LoadProject(project_name);
        }

        //WikiBugTracker
        public virtual MySettingsManager Settings
        {
            get { return settings_ as MySettingsManager; }
        }

        public MyBugtracker(MySettingsManager settings)
            : base(settings)
        {
            root_manager_ = new RootManager(Settings.Folder);

            Settings.ParameterAfterChange += new Common.ParameterChangeHandler(Settings_ParameterAfterChange);
        }

        void Settings_ParameterAfterChange(object sender, Common.ParameterChangeArgs args)
        {
            if (args.Key == Settings.ParamFolder)
                root_manager_ = new RootManager(args.Value);
        }

        public override List<string> GetProjectsList()
        {
            List<String> name_list = new List<string>();

            FeedProjectList(GetProjects(), ref name_list);

            return name_list;
        }

        public List<string> GetProjects()
        {
            return Root.Projects;
        }
        
        private void FeedProjectList(List<String> projects, ref List<String> name_list)
        {
            foreach (var p in projects)
            {
                if (!name_list.Contains(p))
                {
                    name_list.Add(p);

                    FeedProjectList(GetSubProjectsList(p), ref name_list);
                }
            }
        }

        public override int ProjectAdd(string project_name, string project_description)
        {
            if (!ProjectExists(project_name))
            {
                Root root = Root;

                Int64 project_id = root.AddProject(project_name);
                Project project = new Project(project_id, project_name, project_description);

                RootManager.WriteProject(project);
                RootManager.WriteRoot(root);

                return (int)project_id;
            }

            return -1;
        }

        public override void ProjectDelete(string project_name)
        {
            if (ProjectExists(project_name))
            {
                throw new NotImplementedException();
            }
        }

        public override void ProjectEdit(string old_project_name, string new_project_name, string project_description)
        {
            if (ProjectExists(old_project_name) && !ProjectExists(new_project_name))
            {
                // This is to rename all project that have a dependence on the old project
                // This need to be done before the project is modified if the project uses
                // itself as a subproject (we will try to prevent it, but just in case)
                if (old_project_name.ToUpperInvariant() != new_project_name.ToUpperInvariant())
                    RenameProject(old_project_name, new_project_name);

                Project project = Project(old_project_name);

                project.Name = new_project_name;
                project.Description = project_description;

                // This is to move the data to the new folder
                // This need to be done after the project is modified if the project uses
                // itself as a subproject (we will try to prevent it, but just in case)
                if (old_project_name.ToUpperInvariant() != new_project_name.ToUpperInvariant())
                    RootManager.RenameProject(old_project_name, new_project_name);

                RootManager.WriteProject(project);
            }
        }

        private void RenameProject(string old_project_name, string new_project_name)
        {
            List<string> projects_list = GetProjectsList();

            foreach (var p in projects_list)
            {
                Project project = Project(p);

                if (project.Projects.Contains(old_project_name))
                {
                    int index = project.Projects.IndexOf(old_project_name);
                    project.Projects.RemoveAt(index);
                    project.Projects.Insert(index, new_project_name);
                    RootManager.WriteProject(project);
                }
            }

            Root root = Root;

            if (root.Projects.Contains(old_project_name))
            {
                int index = root.Projects.IndexOf(old_project_name);
                root.Projects.RemoveAt(index);
                root.Projects.Insert(index, new_project_name);
                RootManager.WriteRoot(root);
            }
        }

        public override List<string> GetSubProjectsList(string project_name)
        {
            if (String.IsNullOrEmpty(project_name))
            {
                return GetProjects();
            }

            if (ProjectExists(project_name))
            {
                return Project(project_name).Projects;
            }

            return null;
        }

        public override int SubProjectAdd(string parent_project_name, string project_name, string project_description)
        {
            if (!ProjectExists(project_name) && ProjectExists(parent_project_name))
            {
                Root root = Root;
                Int64 project_id = root.GetNextProjectID();
                RootManager.WriteRoot(root);

                Project project = Project(parent_project_name);
                project.AddProject(project_name);
                RootManager.WriteProject(project);

                project = new Project(project_id, project_name, project_description);
                RootManager.WriteProject(project);

                return (int)project_id;
            }

            return -1;
        }

        public override dsData.dtIssueDataDataTable GetIssuesList(string project_name, string targeted_milestone, string issue_status)
        {
            throw new NotImplementedException();
        }

        public override string IssueAdd()
        {
            throw new NotImplementedException();
        }

        public override int IssueDelete()
        {
            throw new NotImplementedException();
        }

        public override int IssueAttachmentAdd(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueAttachmentGet(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueAttachmentDelete(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueAttachmentRename(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueAttachmentView(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueNoteAdd(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueNoteDelete(string issue_id)
        {
            throw new NotImplementedException();
        }

        public override int IssueNoteEdit(string issue_id)
        {
            throw new NotImplementedException();
        }
    }
}
